﻿using Abp.Domain.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using Abp.Extensions;
using Abp.Linq.Extensions;
using System.Threading.Tasks;
using System.Data.Entity;
using Abp.AutoMapper;
using Abp.Application.Services.Dto;
using MyCompanyName.AbpZeroTemplate.Prm.Admin.Dto;
using Abp.Domain.Uow;

namespace MyCompanyName.AbpZeroTemplate.Prm.Admin
{
    public class SubstanceAppService : AbpZeroTemplateAppServiceBase, ISubstanceAppService
    {
        private readonly SubstanceManager substanceManager;
        private IRepository<Project.ProjectInfo, int> projectRepository;
        private IRepository<Inquiry.Inquiry, int> inquiryRepository;
        public SubstanceAppService(SubstanceManager _substanceManager,
            IRepository<Project.ProjectInfo, int> _projectRepository,
            IRepository<Inquiry.Inquiry, int> _inquiryRepository
            )
        {
            substanceManager = _substanceManager;
            projectRepository = _projectRepository;
            inquiryRepository = _inquiryRepository;
        }

        public Abp.Application.Services.Dto.PagedResultOutput<Dto.SubstanceOutPut> GetAll(Dto.GetSubstanceInPut input)
        {

            int subcount = 0;

            var query = substanceManager.PageList(input.cas, input.cnName, input.enName, input.keyword, input.Sorting, input.SkipCount, input.MaxResultCount, out subcount);

            var sublistdtos = new List<SubstanceOutPut>();

            foreach (Abp.Mtrl.Material item in query)
            {
                sublistdtos.Add(new SubstanceOutPut()
                {
                    CAS = item.CASNo,
                    CDX = item.CdxFile != null ? System.Text.Encoding.Default.GetString(item.CdxFile) : string.Empty,
                    ChemDrawName = string.Empty,
                    CnName = item.CnName,
                    EnName = item.EnName,
                    Formula = item.MolecularFormula,
                    HighRisk = item.RiskStatements,
                    Id = item.Id,
                    MOL = item.MolString,
                    MolecularWeight = item.MolecularWeight,
                    MolPngBase64 = item.ImgFile != null ? Convert.ToBase64String(item.ImgFile) : string.Empty,
                    Note = string.Empty,
                    Products = null
                });
            }


            return new PagedResultOutput<SubstanceOutPut>(
                subcount,
                sublistdtos
                );
        }


        public void RemoveProduct(int productId = 0)
        {
            if (productId > 0)
            {
               var p= substanceManager.productRepository.Get(productId);
               var pOther = substanceManager.productRepository.GetAll().Where(x => x.Code == p.Code && x.Id != productId).FirstOrDefault();
               if (pOther != null)
               {
                   substanceManager.productRepository.Delete(p);

                   ProductNoChange(0, "", p.SubstanceId, "");
               }
               else
               { 
               //判断当前有没有引用的项目；
                   if (!projectRepository.GetAll().Any(x => x.ProductNo == p.Code))
                   {
                       substanceManager.productRepository.Delete(p);
                       ProductNoChange(0, "", p.SubstanceId, "");
                   }
                   else
                   {
                       throw new Abp.UI.UserFriendlyException("系统提示", "当前产品有项目，不能删除");
                   }
               }

            }
        }

        public void CreateSubstance(CreateSubstanceInput input)
        {

            if (input.Id > 0)
            {
                var sub = substanceManager.Get(input.Id);
                sub.CASNo = input.CAS;
                sub.CnName = input.CnName;
                sub.MolecularFormula = input.Formula;
                sub.MolecularWeight = input.MolecularWeight;
                sub.MolString = input.MOL;
                sub.EnName = input.EnName;
                sub.CdxFile = Encoding.UTF8.GetBytes(input.CDX);
                sub.RiskStatements = input.HighRisk;
                sub.ImgFile = base64ToByte(input.MolPngBase64);
                substanceManager.Update(sub);
            }
            else
            {
                var sub = new Abp.Mtrl.Material();
                sub.CASNo = input.CAS;
                sub.CnName = input.CnName;
                sub.MolecularFormula = input.Formula;
                sub.MolecularWeight = input.MolecularWeight;
                sub.MolString = input.MOL;
                sub.CdxFile = Encoding.UTF8.GetBytes(input.CDX);
                sub.EnName = input.EnName;
                sub.RiskStatements = input.HighRisk;
                sub.ImgFile = base64ToByte(input.MolPngBase64);
                substanceManager.Save(sub);
            }

        }

        [UnitOfWork(isTransactional: false)]
        public SubstanceOutPut GetById(int id, int productId = 0)
        {
            if (id == 0)
            {
                return new SubstanceOutPut() { };
            }


            var substance = substanceManager.Get(id);
            var product = substanceManager.productRepository.GetAll().Where(x => x.Id == productId).FirstOrDefault();

            if (substance == null)
            {
                return new SubstanceOutPut() { };
            }

            var outPut = new SubstanceOutPut()
            {
                CAS = GetNullString(substance.CASNo),
                CDX = substance.CdxFile == null ? string.Empty : Encoding.UTF8.GetString(substance.CdxFile),
                ProductNo = product == null ? "" : product.Code,
                ProductId = productId,
                Note = string.Empty,
                MolPngBase64 = substance.ImgFile == null ? string.Empty : Convert.ToBase64String(substance.ImgFile),
                MolecularWeight = GetNullString(substance.MolecularWeight),
                MOL = GetNullString(substance.MolString),
                Id = substance.Id,
                HighRisk = GetNullString(substance.RiskStatements),
                Formula = GetNullString(substance.MolecularFormula),
                ChemDrawName = string.Empty,
                CnName = GetNullString(substance.CnName),
                EnName = GetNullString(substance.EnName)
            };
            return outPut;
        }

        public string GetNullString(string aa)
        {
            if (string.IsNullOrEmpty(aa))
            {
                return string.Empty;
            }
            else
            {
                return aa;
            }

        }

        [UnitOfWork(isTransactional: false)]
        public int SetSubstanceProduct(CreateProductInPut input)
        {
            if (!input.hiddenNo)
            {
                if (string.IsNullOrEmpty(input.ProductNo))
                {
                    throw new Abp.UI.UserFriendlyException("系统提示", "产品号不能为空");
                }

                if (input.ProductId == 0)
                {
                    if (substanceManager.productRepository.GetAll().Any(x => input.ProductNo == x.Code))
                    {
                        throw new Abp.UI.UserFriendlyException("系统提示", "产品号已经使用");
                    }
                }
                else
                {
                    if (substanceManager.productRepository.GetAll().Any(x => input.ProductNo == x.Code && x.Id != input.ProductId))
                    {
                        throw new Abp.UI.UserFriendlyException("系统提示", "产品号已经使用");
                    }
                }
            }
            var sub = new Abp.Mtrl.Material();

            if (!string.IsNullOrWhiteSpace(input.CAS))
            {
                var subs = substanceManager.Query(new List<string>() { input.CAS }, new List<string>(), new List<string>(), new List<string>());
                if (subs.Count > 0)
                {
                    sub = subs[0];
                }
                else
                {
                    sub.Id = input.SubstanceId;
                }
            }
            else if (!string.IsNullOrWhiteSpace(input.EnName))
            {
                var subs = substanceManager.Query(new List<string>(), new List<string>(), new List<string>() { input.EnName }, new List<string>());
                if (subs.Count > 0)
                {
                    sub = subs[0];
                }
                else
                {
                    sub.Id = input.SubstanceId;
                }
            }
            else if (!string.IsNullOrWhiteSpace(input.CnName))
            {
                var subs = substanceManager.Query(new List<string>(), new List<string>() { input.CnName }, new List<string>(), new List<string>());
                if (subs.Count > 0)
                {
                    sub = subs[0];
                }
                else
                {
                    sub.Id = input.SubstanceId;
                }
            }
            else
            {
                sub.Id = input.SubstanceId;
            }

            int oldProductSubId = 0;
            string oldProductNo = "";

            if (input.ProductId > 0)
            {
                var p = substanceManager.productRepository.Get(input.ProductId);
                oldProductSubId = p.SubstanceId;
                oldProductNo = p.Code;
            }

            sub.Id = input.SubstanceId;
            sub.CASNo = input.CAS;
            sub.CdxFile = Encoding.UTF8.GetBytes(input.CDX);
            sub.MolecularFormula = input.Formula;
            sub.MolecularWeight = input.MolecularWeight;
            sub.MolString = input.Mol;
            sub.EnName = input.EnName;
            sub.CnName = input.CnName;
            sub.RiskStatements = input.HighRisk;
            sub.ImgFile = base64ToByte(input.MolPngBase64);

            var product = new Product() { Id = input.ProductId, Code = input.ProductNo };
            int subId = substanceManager.SetSubstanceProduct(sub, input.hiddenNo, product);

            if (!input.hiddenNo && !string.IsNullOrWhiteSpace(product.Code))
            {
                ProductNoChange(subId, product.Code, oldProductSubId, oldProductNo);
            }


            return subId;
        }

        /// <summary>
        /// 产品号的调整；
        /// </summary>
        /// <param name="newProductSubId"></param>
        /// <param name="newProductNo"></param>
        /// <param name="oldProductSubId"></param>
        /// <param name="oldProductNo"></param>
        private void ProductNoChange(int newProductSubId, string newProductNo, int oldProductSubId = 0, string oldProductNo = "")
        {
            /*
            * productId>0-----改变项目的Code编号；
            * 更新询盘的编号；（旧的SubId--》）
            * 
            * productId >0 根据旧的SubId---》调整新的
            * 
            * productId ==0 ;直接根据新的SubId更新---
            * 
            */
            //更新询盘处的---九洲编号
            //更新项目的Code编号

            if (!string.IsNullOrWhiteSpace(oldProductNo))
            {
                //更新项目的新的编号；
                var upProjects = projectRepository.GetAll().Where(x => x.ProductNo == oldProductNo).ToList();
                foreach (var item in upProjects)
                {
                    item.ProductNo = newProductNo;
                    projectRepository.Update(item);
                }
            }


            var inquirys = inquiryRepository.GetAll().Where(x => x.SubId == newProductSubId).ToList();
            foreach (var item in inquirys)
            {
                item.InquiryNo = newProductNo;
            }

            if (oldProductSubId > 0 && oldProductSubId != newProductSubId)
            {
                var removeInquirys = inquiryRepository.GetAll().Where(x => x.SubId == oldProductSubId).ToList();
                foreach (var item in removeInquirys)
                {
                    item.InquiryNo = "";
                }
            }

        }


        private byte[] base64ToByte(string base64)
        {
            if (string.IsNullOrEmpty(base64))
            {
                return null;
            }
            else
            {
                return Convert.FromBase64String(base64);
            }
        }


        /// <summary>
        /// 取得分子式和分子量以及结构式图片
        /// </summary>
        /// <param name="mol"></param>
        /// <returns></returns>

    }
}
